<template>
  <div>
     <!-- 面包屑导航区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>商品管理</el-breadcrumb-item>
        <el-breadcrumb-item>商品分类</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片视图区域 -->
    <el-card>
        <!-- 添加区域 -->
        <el-row>
            <el-col><el-button type="primary" @click="showAddCateDialog">添加商品</el-button></el-col>
        </el-row>

        <!-- 表格 -->
        <!-- columns:为table下的列指定 标题 和 数据来源(cateList.xxx的属性名)  
         selection-type: 是否显示复选框 
         expand-type: 是否为展开行类型表单
         show-index: 显示索引列 
         index-text: 子第一索引列的标题 
         border:是否有隔行边框
         show-row-hover: 是否有鼠标经过，该行变色 -->
        <tree-table 
        :data='cateList'
        :columns="columns"
        :selection-type="false"
        :expand-type='false'
        show-index
        index-text='#'
        border
        :show-row-hover="false">
        <!-- (在表格中间定义插槽)
             slot：指定插槽的名字(和columns中的{}.template对应)
             该插槽会被 template:'isok' 列所引用 
             slot-scope：接收这一行的数据 -->
        <template slot="isok" slot-scope="scope">
            <!-- 如果cat_delete==false，就显示√，反之，显示❌ -->
            <i style="color:lightgreen;" class="el-icon-success" v-if="scope.row.cat_deleted===false"></i>
            <i style="color:lightgreen;" class="el-icon-error" v-else></i>
        </template>
        <!-- 定义排序插槽 -->
        <template slot="order" slot-scope="scope">
            <!-- 进行判断渲染，如果level=0，渲染出一级。。。 -->
            <el-tag size="mini" v-if="scope.row.cat_level===0">一级</el-tag>
            <el-tag size="mini" type="success" v-else-if="scope.row.cat_level===1">二级</el-tag>
            <el-tag size="mini" type="warning" v-else>三级</el-tag>
        </template>
        <!-- 定义操作插槽 -->
        <template slot="operation" slot-scope="scope">
           <el-button size="mini" type="primary" icon="el-icon-edit" @click="editCateName(scope.row.cat_id)">编辑</el-button>
           <el-button  size="mini" type="danger" icon="el-icon-delete" @click="removeCateById(scope.row.cat_id)">删除</el-button>
        </template>
        </tree-table>

        <!-- 分页区域 -->
        <!-- size-change: 监听每页显示多少条数据的改变(page-size)
             current-change：监听当前页码值的变化(current-page)
             current-page：当前的页码
             page-size：每页显示的数据
             page-sizes：供page-size选择的数组
             layout: 该分页区域的组成部分
             total：总数据条数-->
         <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="queryInfo.pagenum"
            :page-sizes="[3, 5, 10, 15]"
            :page-size="queryInfo.pagesize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total">
         </el-pagination>
    </el-card>
<!-- 新版本在cascaderProps  里配置checkStrictly:true, -->
    <!-- 添加分类的对话框 -->   
    <el-dialog
    title="添加分类"
    :visible.sync="addCateDialogVisible"
     @close='addCateDialogColsed'
    width="50%">
    <el-form :model="addCateFrom"
     :rules="addCateFromRules" 
     ref="addCateFromRef" 
     label-width="100px">
        <el-form-item label="分类名称：" prop="cat_name">
            <el-input v-model="addCateFrom.cat_name"></el-input>
        </el-form-item>
        <el-form-item label="父级分类：">
            <!-- cascader级联选择器
                :options: 指定数据源
                :props：指定配置选项
                change：当选中节点变化时触发(当我们选择或切换 选择项时，触发该函数) -->
           <el-cascader
            v-model="selectedKeys"
            :options="parentCateList"
            :props="cascaderProps"
            clearable
            @change="parentCateChanged"></el-cascader>
        </el-form-item>
    </el-form>   
    <span slot="footer" class="dialog-footer">
        <el-button @click="addCateDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addCate">确 定</el-button>
    </span>
    </el-dialog>

    <!-- 编辑对话框 -->
    <el-dialog
    title="编辑分类"
    :visible.sync="editCateDialog"
    width="50%"
    >
  <el-form :model="editCateFrom" label-width="100px"  :rules="addCateFromRules" 
     ref="editCateFromRef">
    <el-form-item label="分类名称：" prop="cat_name">
        <el-input v-model="editCateFrom.cat_name"></el-input>
    </el-form-item>
  </el-form>
  <span slot="footer" class="dialog-footer">
    <el-button @click="editCateDialog = false">取 消</el-button>
    <el-button type="primary" @click="editCate(editCateFrom.cat_id,editCateFrom.cat_name)">确 定</el-button>
  </span>
</el-dialog>
  </div>
</template>

<script>
export default {
    data() {
        return {
            // 商品分类的数据列表
            cateList:[],
            // 查询条件
            queryInfo:{ 
                type:3, // 获取1,2,3级所有权限
                pagenum:1, // 当前页码值为1
                pagesize:5 // 每页显示多少条数据
            },
            total:0, // 总数据条数
            // 为table指定列的定义
            columns:[{
                label:'分类名称',
                prop:'cat_name'
            },{
                label:'是否有效',
                type:'template',  // 表示将当前列定义为插槽的模板列
                template:'isok'   // 表示当前这一列使用的模板名称 
            },{
                label:'排序',
                type:'template',  // 表示将当前列定义为插槽的模板列
                template:'order'   // 表示当前这一列使用的模板名称 
            },{
                label:'操作',
                type:'template',  // 表示将当前列定义为插槽的模板列
                template:'operation'   // 表示当前这一列使用的模板名称 
            }
            ],
            addCateDialogVisible:false,// 控制添加分类对话框的显示与隐藏
            //添加分类的表单数据对象
            addCateFrom:{  
                cat_name:"", // 将要添加的分类的名称
                cat_pid:0,  // 父级分类的id,默认为0，表示添加的是1级分类(最高)
                cat_level:0  // 分类的等级，默认为0，表示添加的是1级 (最高)
            },  
            // 添加分类表单的验证规则对象
            addCateFromRules:{
                cat_name:[{required:true,message:'请输入分类名称',trigger:'blur'}]
            },
            // 存放父级分类的列表
            parentCateList:[],
            // 指定级联选择器的配置选项
            cascaderProps:{
                expandTrigger: 'hover', // 经过触发
                value:'cat_id',  // 具体选中的属性的值
                label:'cat_name',  //  具体看到的属性的值(我们看到的是lable，但选中是value的值)
                children:'children', // 指定父子嵌套用的是哪个属性 
                checkStrictly:true  // 是否严格的遵守父子节点不互相关联(取消掉只能选择二级权限，可以直接选择一级权限)
            },
            // 被选中的父级分类的id数组
            selectedKeys:[],
            // 被编辑的商品分类
            editCateFrom:{},
            // 用于控制编辑对话框的显示于隐藏
            editCateDialog:false 
        }
    },
    created(){
        this.getCateList()
    },
    methods:{
        // 获取商品分类数据
       async getCateList(){
         const {data:res} = await this.$http.get(`categories`,{params:this.queryInfo})
         if(res.meta.status !== 200){
             return this.$message.error('获取商品分类失败');
          }
        //   把数据列表，赋值给 cateList
          this.cateList = res.data.result
        //   为总数据条数赋值
          this.total = res.data.total
        },
        // 监听pagesize改变的事件
        handleSizeChange(newSize){ // 默认参数：最新的每页要显示的数据
        // 当选中了其他显示数据选项时，为pagesize重新赋值，并重新发起请求
            this.queryInfo.pagesize = newSize
            // 重新发起请求，获取最新数据
            this.getCateList();
        },
        // 监听 pagenum 改变的事件
        handleCurrentChange(newPage){ // 默认参数：最新的页码值
            this.queryInfo.pagenum = newPage
            this.getCateList();
        },
        // 添加按钮，展示添加分类的对话框
        showAddCateDialog(){
            this.getParentCateList()
            this.addCateDialogVisible = true
        },
        // 用于获取父级分类的数据列表
       async getParentCateList(){
            // type:2: 获取一、二，前两级的分类
          const {data:res} = await this.$http.get(`categories`,{params:{type:2}})
          if(res.meta.status !== 200){
              return this.$message.error('获取父级分类失败！')
          }
        this.parentCateList = res.data
        },
        // 级联选择器的 当我们 选中或切换 选择项时 触发这个函数
        parentCateChanged(){
        //    如果selectedKeys 数组中的length > 0,就代表选中了某个父级分类
        //    反之，就说明没有选择任何分类
        if(this.selectedKeys.length > 0){
        //    如果选中了父级分类
        //    数组中，永远将最后一个元素id，作为父级分类
                this.addCateFrom.cat_pid
                 =  
                this.selectedKeys[this.selectedKeys.length-1]
                /*  如果没有选中任何一个父级id，数组长度为0
                就代表，该添加的商品分类，处于最高级的1级分类
                如果长度为1，那么就代表选中了一个一级父分类
                就代表，该添加的商品分类，处于第二级别，有一个父亲
                也就是说：selectedKeys.length 永远等于 cat_level
                (没选length=0，0=0级(最高)，选了1个length=1，1=1级，选了2个length=2，2=2级) */
                this.addCateFrom.cat_level = this.selectedKeys.length   
                return
            }else{
                // 如果length=0，那么就代表，没有选择父级，处于最高级
                // 就将cat_pid、cat_level 都赋值=0，表示没有父级，且处于最高等级
                  this.addCateFrom.cat_pid =0
                  this.addCateFrom.cat_level=0
            }
        },
        // 添加分类的确定按钮，添加新的分类
        addCate(){
          this.$refs.addCateFromRef.validate(async(valid)=>{
            //   如果valid 不通过，则直接return，不发送请求
              if(!valid) return
            //   预校验通过！
            //  post请求，直接把addCateFrom放进去参数就行
            //  get需要{params:}
            const {data:res} = await this.$http.post(`categories`,this.addCateFrom)

            if(res.meta.status !== 201){
                return this.$message.error('添加分类失败!')
            }
            this.$message.success('添加分类成功!')
            this.getCateList() // 刷新分类列表
            this.addCateDialogVisible = false
          })
        },
        // 监听添加分类对话框的关闭,重置表单 
        addCateDialogColsed(){
            // 清空addCateFrom表单数据，避免影响下一次打开
            this.$refs.addCateFromRef.resetFields()
            // 将 保存父id的selectdKeys数组，也要清空
            this.selectedKeys=[]
            // 将 pid(父id)，level(等级) 都清空为0
            this.addCateFrom.cat_level = 0
            this.addCateFrom.cat_pid = 0    
        },
        // 编辑按钮
       async editCateName(id){
          const {data:res} = await this.$http.get(`categories/${id}`)
           if(res.meta.status !== 200){
                return this.$message.error('获取分类失败!')
            }
           this.editCateFrom =  res.data
           this.editCateDialog = true
        },
        // 提交编辑确定按钮
       async editCate(id,name){
              const {data:res} = await this.$http.put(`categories/${id}`,{cat_name:name})
               if(res.meta.status !== 200){
                return this.$message.error('编辑商品分类失败!')
            }
            // 如果成功！
            this.getCateList()
            this.editCateDialog = false
        },
        // 根据id删除商品分类
        async removeCateById(id){
        //    弹框提示,是否删除
          const confirmResult =  await this.$confirm('是否删除该商品分类?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
          }).catch(err=>{return err})   // catch捕获错误,将取消行为返回给confirmResult

        // 如果用户点击确定,则返回值是字符串: confirm
        // 点击取消,则返回值字符串:cancel
        //   console.log(confirmResult);  
        //对confirmResult 进行判断,如果是 confirmResult则表示用户真的想要删除
        if(confirmResult === 'cancel'){
            return this.$message('已取消删除')
        }
        // 如果用户确定删除:
        const {data:res} = await this.$http.delete(`categories/${id}`) // 传入id,删除
        if(res.meta.status !== 200){
            return this.$message.error('删除失败')
        }
        this.$message.success('已将该商品分类删除!')
        this.getCateList();
       },
    }
}   
</script>

<style lang="less" scoped>
.el-pagination{
    margin-top: 20px;
}
.el-card{
    .el-row{
        margin-bottom: 20px;
    }
}
.el-cascader{
    width: 100%;
}

</style>